
/*
* Copyright:
* Daniel D. Neilson (ddneilson@ieee.org)
* University of Saskatchewan
* All rights reserved
*
* Permission granted to use for use in assignments and
* projects for CMPT 485 & CMPT 829 at the University
* of Saskatchewan.
*/

#include <cstdint>
#include "octahedron.h"

namespace Object
{
	namespace Models
	{

		// Vertices, normals, and texture coordinates for an octahedron
		static const uint32_t NUM_VERTS = 24;
		static gml::vec3_t _verts[NUM_VERTS] =
		{
			gml::vec3_t(0.0f, 1.0f, 0.0f),
			gml::vec3_t(1.0f, 0.0f, 0.0f),
			gml::vec3_t(0.0f, 0.0f, -1.0f),

			gml::vec3_t(0.0f, 1.0f, 0.0f),
			gml::vec3_t(0.0f, 0.0f, -1.0f),
			gml::vec3_t(-1.0f, 0.0f, 0.0f),

			gml::vec3_t(0.0f, 1.0f, 0.0f),
			gml::vec3_t(-1.0f, 0.0f, 0.0f),
			gml::vec3_t(0.0f, 0.0f, 1.0f),

			gml::vec3_t(0.0f, 1.0f, 0.0f),
			gml::vec3_t(0.0f, 0.0f, 1.0f),
			gml::vec3_t(1.0f, 0.0f, 0.0f),

			gml::vec3_t(1.0f, 0.0f, 0.0f),
			gml::vec3_t(0.0f, -1.0f, 0.0f),
			gml::vec3_t(0.0f, 0.0f, -1.0f),

			gml::vec3_t(0.0f, 0.0f, -1.0f),
			gml::vec3_t(0.0f, -1.0f, 0.0f),
			gml::vec3_t(-1.0f, 0.0f, 0.0f),

			gml::vec3_t(-1.0f, 0.0f, 0.0f),
			gml::vec3_t(0.0f, -1.0f, 0.0f),
			gml::vec3_t(0.0f, 0.0f, 1.0f),

			gml::vec3_t(0.0f, 0.0f, 1.0f),
			gml::vec3_t(0.0f, -1.0f, 0.0f),
			gml::vec3_t(1.0f, 0.0f, 0.0f)

		};
		static gml::vec3_t _normals[NUM_VERTS] =
		{
			gml::normalize( gml::vec3_t(1.0,1.0,-1.0) ),
			gml::normalize( gml::vec3_t(1.0,1.0,-1.0) ),
			gml::normalize( gml::vec3_t(1.0,1.0,-1.0) ),

			gml::normalize( gml::vec3_t(-1.0,1.0,-1.0) ),
			gml::normalize( gml::vec3_t(-1.0,1.0,-1.0) ),
			gml::normalize( gml::vec3_t(-1.0,1.0,-1.0) ),

			gml::normalize( gml::vec3_t(-1.0,1.0,1.0) ),
			gml::normalize( gml::vec3_t(-1.0,1.0,1.0) ),
			gml::normalize( gml::vec3_t(-1.0,1.0,1.0) ),

			gml::normalize( gml::vec3_t(1.0,1.0,1.0) ),
			gml::normalize( gml::vec3_t(1.0,1.0,1.0) ),
			gml::normalize( gml::vec3_t(1.0,1.0,1.0) ),

			gml::normalize( gml::vec3_t(1.0,-1.0,-1.0) ),
			gml::normalize( gml::vec3_t(1.0,-1.0,-1.0) ),
			gml::normalize( gml::vec3_t(1.0,-1.0,-1.0) ),

			gml::normalize( gml::vec3_t(-1.0,-1.0,-1.0) ),
			gml::normalize( gml::vec3_t(-1.0,-1.0,-1.0) ),
			gml::normalize( gml::vec3_t(-1.0,-1.0,-1.0) ),

			gml::normalize( gml::vec3_t(-1.0,-1.0,1.0) ),
			gml::normalize( gml::vec3_t(-1.0,-1.0,1.0) ),
			gml::normalize( gml::vec3_t(-1.0,-1.0,1.0) ),

			gml::normalize( gml::vec3_t(1.0,-1.0,1.0) ),
			gml::normalize( gml::vec3_t(1.0,-1.0,1.0) ),
			gml::normalize( gml::vec3_t(1.0,-1.0,1.0) )
		};
		static gml::vec2_t _texcoords[NUM_VERTS] =
		{
			gml::vec2_t(0.125f, 0.0f),
			gml::vec2_t(0.0f, 0.5f),
			gml::vec2_t(0.25f, 0.5f),

			gml::vec2_t(0.375f, 0.0f),
			gml::vec2_t(0.25f, 0.5f),
			gml::vec2_t(0.5f, 0.5f),

			gml::vec2_t(0.625f, 0.0f),
			gml::vec2_t(0.5f, 0.5f),
			gml::vec2_t(0.75f, 0.5f),

			gml::vec2_t(0.875f, 0.0f),
			gml::vec2_t(0.75f, 0.5f),
			gml::vec2_t(1.0f, 0.5f),

			gml::vec2_t(0.0f, 0.5f),
			gml::vec2_t(0.125f, 1.0f),
			gml::vec2_t(0.25f, 0.5f),

			gml::vec2_t(0.25f, 0.5f),
			gml::vec2_t(0.375f, 1.0f),
			gml::vec2_t(0.5f, 0.5f),

			gml::vec2_t(0.5f, 0.5f),
			gml::vec2_t(0.625f, 1.0f),
			gml::vec2_t(0.75f, 0.5f),

			gml::vec2_t(0.75f, 0.5f),
			gml::vec2_t(0.875f, 1.0f),
			gml::vec2_t(1.0f, 0.5f)
		};
		static GLuint _indices[8*3] =
		{
			0, 1, 2,
			3, 4, 5,
			6, 7, 8,
			9, 10, 11,
			12, 13, 14,
			15, 16, 17,
			18, 19, 20,
			21, 22, 23
		};

		Octahedron::Octahedron() {}
		Octahedron::~Octahedron() {}

		bool Octahedron::init()
		{
			return m_mesh.init(GL_TRIANGLES, NUM_VERTS, _verts, _normals, _texcoords, 8*3, _indices);
		}

		void Octahedron::rasterize() const
		{
			m_mesh.rasterize();
		}

		bool Octahedron::rayIntersects(const RayTracing::Ray_t &ray, const float t0, const float t1, RayTracing::HitInfo_t &hitinfo) const
		{
			return m_mesh.rayIntersects(ray, t0, t1, hitinfo);
		}
		bool Octahedron::shadowsRay(const RayTracing::Ray_t &ray, const float t0, const float t1) const
		{
			return m_mesh.shadowsRay(ray, t0, t1);
		}
		void Octahedron::hitProperties(const RayTracing::HitInfo_t &hitinfo, gml::vec3_t &normal, gml::vec2_t &texCoords) const
		{
			m_mesh.hitProperties(hitinfo, normal, texCoords);
		}

		RayTracing::HitInfo_t* Octahedron::rayIntersectsInParallel(const RayTracing::Ray_t *rays, const float t0, const float t1, const int w, const int h, int objHitIndex) const
		{

			//raysIntersectsWithCudaPlane(float *devRays, const float t0, const float t1, const int w, const int h, RayTracing::HitInfo_t *hostHitInfos);
			return 0;
		}

		float* Octahedron::hitPropertiesInParallel(const RayTracing::HitInfo_t *hitinfos,  const int w, const int h) const
		{
			return NULL;
		}

		RayTracing::GeometryType_Kernel Octahedron::getGeometryType() const
		{
			return RayTracing::GeometryType_Kernel::OCTAHEDRON;
		}

		bool* Octahedron::shadowRaysInParallel(const RayTracing::Ray_t *rays, const RayTracing::HitInfo_t *hitinfos,const RayTracing::Object_Kernel_t *objects, const float* lightProp, const int w, const int h) const
		{
			return NULL;
		}
	}
}
